<script>
import Select from 'ant-design-vue/es/select'
import { ellipsisFunc } from './utils';
export default {
    name: 'ZkSelect',
    props: {
        value: {
            type: [String, Number, Boolean, Object, Array],
            default: () => undefined
        },
        options: {
            type: [Array, Function],
            default: () => []
        },
        disabled: {
            type: Boolean,
            default: false
        },
        placeholder: {
            type: [String, Object],
            default: () => '请选择'
        },
        /** 下拉选择模式 默认:default 多选:multiple */
        mode: {
            type: String,
            default: () => 'default'
        },
        /** 是否有搜索功能 */
        hasSearch: {
            type: Boolean,
            default: () => false
        },
        /** 
         * 是否支持自由输入
         */
        freeIn: {
            type: Boolean,
            default: () => false
        },
        /** 是否支持清除 */
        allowClear: {
            type: Boolean,
            default: () => false,
        },
        // 如果发现下拉菜单跟随页面滚动，或者需要在其他弹层中触发 Select，请尝试使用 getPopupContainer={triggerNode => triggerNode.parentNode} 将下拉弹层渲染节点固定在触发器的父元素中
        getPopupContainer: {
            type: Function,
            default: triggerNode => triggerNode.parentNode,
        },
        /** 最多显示多少个 tag */
        maxTagCount: {
            type: Number,
            default: () => 10
        },
        /** tag最多内容数 */
        maxTagTextLength: {
            type: Number,
            default: () => 10
        },
        maxTagPlaceholder: {
            type: Function
        },
        /** 是否关闭多选标签 */
        noTag: {
            type: Boolean,
            default: () => false
        },
        /** 搜索下拉初始化时是否立即加载 */
        isInitLoadForSearch: {
            type: Boolean,
            default: () => false
        },
    },
    data() {
        return {
            optionsData: [
                // {label:'',value:'null'},
            ]
        }
    },
    created() {
        if (this.hasSearch&&!this.isInitLoadForSearch) {
            // 搜索下拉在搜索时触发下拉
            return;
        }
        // 常规下拉,初始化时加载待选项
        if (this.options instanceof Array) {
            this.optionsData = this.options;
        } else {
            this.options().then((result) => {
                this.optionsData = result;
            });
        }
    },
    render() {
        const props = Object.keys(this.$props).filter(key => key != 'options' && key != 'value').reduce((res, key) => {
            res[key] = this[key];
            return res;
        }, {});
        const inOptions = this.$props.options;
        let value = this.$props.value;

        //#region 强制转换已选数据为字符串
        if (value instanceof Array) {
            value = value.map(i => formatVal(i));
        } else {
            value = formatVal(value);
        }
        //#endregion

        const onChange = (value, option) => {
            if (props.hasSearch) {
                // 修复搜索时空内容触发搜索 BUG
                if(value===undefined||(''+value).trim()===""){
                    this.optionsData = [];
                    emitValue(this,value, option);
                    return;
                }  
            }

            if (value&&props.mode != 'multiple') {
                // 清空变化和多选选中导致的变化才会提交值
                return;
            }
            emitValue(this,value, option);
        }

        const onSelect = (value, option) => {
            if (value&&props.mode == 'multiple') {
                return;
            }
            emitValue(this,value, option);
        }

        const onSearch = (val) => {
            if (props.hasSearch) {
                // 修复搜索时空内容触发搜索 BUG
                if(val===undefined||(''+val).trim()===""){
                    this.optionsData = [];
                    return;
                }  
            }
            inOptions(val).then((result) => {
                if (props.freeIn) {
                    if (!result.find(i => i.label === val) && val != "") {
                        // 是否支持自定义输入内容
                        result.unshift({ label: val, value: val });
                    }
                    // 同名去重
                    const obj = {};
                    result.forEach(i => {
                        obj[i.label] = i.value;
                    });
                    result = Object.keys(obj).map(label => ({
                        label: label,
                        value: obj[label]
                    }));
                }

                // 非搜索使用常规待选项 
                this.optionsData = [...result.map(i => {
                    i.value = formatVal(i.value);
                    return i;
                })];

                console.log('search', this.optionsData);
            });
        }
        if (props.mode != "multiple"&&!props.hasSearch) {
            if (this.optionsData.length > 0 && this.optionsData.find(i => i.value == value)) {
                // 纯下拉检测是否有待选项,若无相应选项则是未选择
                props.value = value;
            } else {
                props.value = undefined;
            }
        } else {
            props.value = value;
        }
        if (props.hasSearch) {
            if (typeof inOptions != "function") {
                throw Error('zk-select开启search搜索时options需传入返回Promise对象的方法');
            }
            return (
                <a-select {...{ props }} showSearch={props.hasSearch} onChange={onChange} onSearch={onSearch} onSelect={onSelect} filterOption={false}>
                    {
                        this.optionsData.map(i => (
                            <a-select-option key={i.value} ext={i}> 
                                {i.label}
                            </a-select-option>
                        ))
                    }
                </a-select>
            )
        } else {
            // 非搜索使用常规待选项 
            props.options = this.optionsData.map(i => {
                i.value = formatVal(i.value);
                return i;
            });
            if (this.noTag && this.mode == 'multiple' && !props.maxTagPlaceholder) {
                // 多选且无标签
                // props.maxTagPlaceholder = (omittedValues,record)=>{
                //     if (!record.value) return '';
                //     const arr = record.value.map(val=>{
                //         const item = props.options.find(i=>i.value==val);
                //         if (!item) {
                //             return '';
                //         }
                //         return item.label;
                //     });
                //     return ellipsisFunc(arr.join(','),100);
                // }
            }
            return (
                <a-select {...{ props }} showSearch={false} onChange={onChange} onSelect={onSelect}></a-select>
            )
        }
    },
    methods: {
        refresh() {
            if (this.options instanceof Array) return Promise.resolve();
            return this.options().then((res) => {
                this.optionsData = res;
            });
        }
    }
}

function formatVal(value) {
    // 非 boolean
    if (typeof value !== 'boolean' && value !== undefined) {
        return '' + value;
    }
    return value;
}

function emitValue(ctx, value, option) {
    if (value == 'null') {
        value = null;
    }
    ctx.$emit('input', value, option);
    ctx.$listeners.change && ctx.$listeners.change(value, option);
}
</script>

